package com.ruoyi.common.wxServe;

//import cn.hutool.core.codec.Base64;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
//import com.ruoyi.common.constant.ConstWeiChat;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
//import com.ruoyi.common.utils.v2.*;
import com.ruoyi.common.wxServe.bo.Auth2SessionBo;
import com.ruoyi.common.wxServe.bo.WeiXinInfo;
//import com.ruoyi.common.wxServe.bo.weixin_v3.CheckPayResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;

import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.security.spec.AlgorithmParameterSpec;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信相关服务
 * @author bing.li
 * @date 2021/8/27  14:10
 */
@Service
@Slf4j
public class WeChatServe {

    @Autowired
    private WeiXinInfo weiXinInfo;
    @Autowired
    private RestTemplate restTemplate;

   // @Autowired
//    private CloseableHttpClient httpClient;

    /**
     * 微信退款
     * @param outTradeNo  本地订单号，
     * @param outRefundNo 退款订单号，商户系统内部的退款单号，商户系统内部唯一，只能是数字、大小写字母_-|*@
     * @param totalMoney 订单总金额 分
     * @param refundFee  退款金额  分
     * @param refundDesc  若商户传入，会在下发给用户的退款消息中体现退款原因 <1元，部分退款不显示
     * @return
     */
//    public void weiXinRefund(String outTradeNo,String outRefundNo,String totalMoney,String refundFee,String refundDesc){
//        Map<String, String> resultMap = new HashMap<>();
//        Map<String, String> parameters = new HashMap<>();
//        //生产环境回调地址
//        String notify_url = ConstWeiChat.HUI_DIAO_URL + ConstUrl.PRE_WEI_XIN_PATH + ConstWeiChat.WEI_XIN_REFUND_URL;
//        try {
//            parameters = WXPayUtil.genParamToMapRefund(ConfigUtil.MCH_ID, outTradeNo, outRefundNo, totalMoney, refundFee,refundDesc, notify_url);
//            String requestXML = WXPayUtil.mapToXml(parameters);
//            String result = HttpCilentUtil.postForobject(ConfigUtil.REFUND_URL, requestXML,"");
//            System.out.println("发送退款，返回结果数据："+result);
//            //解析退款返回信息
//            resultMap = WXPayUtil.xmlToMap(result);
//            if (resultMap.get("return_code").equals("FAIL")) {
//                throw new CustomException(resultMap.get("return_msg"));
//            }
//            if (resultMap.get("result_code").equals("FAIL")) {
//                throw new CustomException("请求成功，但提交退款业务失败，失败原因：" + resultMap.get("err_code_des"));
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//            log.error("发起申请退款异常，异常信息：{}", e.getMessage());
//        }
//
//    }



    /**
     * 根据本地订单号，查询订单支付详情
     * @param outTradeNo  商户系统内部订单号，只能是数字、大小写字母_-*且在同一个商户号下唯一
     */
//    public Map<String, String> checkOrderV2PayStatus(String outTradeNo){
//        Map<String, String> paraMap = new HashMap<>();
//        Map<String, String> map = null;
//        paraMap.put("appid", ConfigUtil.APPID);
//        paraMap.put("mch_id", ConfigUtil.MCH_ID);
//        paraMap.put("nonce_str", WXPayUtil.generateNonceStr());   //随机字符串，长度要求在32位以内。
//        paraMap.put("out_trade_no", outTradeNo);
//        try {
//            //设置签名
//            String sign = WXPayUtil.generateSignature(paraMap, ConfigUtil.API_KEY);
//            paraMap.put("sign", sign);
//            //封装请求参数结束
//            String requestXML= WXPayUtil.mapToXml(paraMap);
//
//            //调用查询订单接口
//            String result = HttpCilentUtil.postForobject(ConfigUtil.ORDER_QUERY, requestXML);
////            System.err.println(result);
//            //将xml格式的字符串转成 map
//             map  = WXPayUtil.xmlToMap(result);
//        } catch (Exception e) {
//            log.error("订单查询 操作异常 本地单号：{} 异常信息：{}",outTradeNo,e.getMessage());
//        }
//        return map;
//
//    }


    /**
     *  V2统一下单
     * @param total 总金额 分
     * @param description 商品描述
     * @param openid 支付者openid
     * @param outTradeNo 商户系统内部订单号，只能是数字、大小写字母_-*且在同一个商户号下唯一
     * @throws IOException
     * @return prepay_id 预付订单id
     */
//    public  Map<String, String> createV2Order(Integer total,String description,String openid,String outTradeNo){
//        final HttpServletRequest request = ServletUtils.getRequest();
//        Map<String, String> parameters = new HashMap<>();
//        Map<String, String> parameterMap2 = new HashMap<>();
//        String notify_url = ConstWeiChat.HUI_DIAO_URL + ConstUrl.PRE_WEI_XIN_PATH + ConstWeiChat.WEI_XIN_HUI_DIAO_URL;
//        try {
//            parameters = WXPayUtil.genParamToMap(ConfigUtil.MCH_ID, description, "跑腿支付", outTradeNo, total.toString(), CommonUtil.toIpAddr(request), openid,notify_url);
//            String requestXML = WXPayUtil.mapToXml(parameters);
//           // System.err.println(requestXML);
//            String result = HttpCilentUtil.postForobject(ConfigUtil.UNIFIED_ORDER_URL, requestXML);
//            //System.out.println(result);
//            /**统一下单接口返回正常的prepay_id，再按签名规范重新生成签名后，将数据传输给APP。参与签名的字段名为appId，partnerId，prepayId，nonceStr，timeStamp，package。注意：package的值格式为Sign=WXPay**/
//            final Map<String, String> map = WXPayUtil.xmlToMap(result);
//            if (map.get("return_code").equals("FAIL")) {
//                throw new CustomException(map.get("return_msg"));
//            }
//            if(map.get("result_code").equals("FAIL")){
//                throw new CustomException(map.get("err_code_des"));
//            }
//
//            String noncestr = WXPayUtil.generateNonceStr();
//            String timestamp = System.currentTimeMillis() + "";
//            parameterMap2.put("appId", ConfigUtil.APPID);
//            //parameterMap2.put("partnerid", ConfigUtil.MCH_ID);
//            //parameterMap2.put("prepayid", map.get("prepay_id"));
//            parameterMap2.put("package", "prepay_id="+map.get("prepay_id"));
//            parameterMap2.put("nonceStr", noncestr);
//            parameterMap2.put("timeStamp", timestamp);
//            parameterMap2.put("signType", "MD5");
//            String sign2 = WXPayUtil.generateSignature(parameterMap2, ConfigUtil.API_KEY);
//            parameterMap2.put("sign", sign2);
//
//
//            //parameterMap2.put("orderCode", outTradeNo);
//            //System.out.println(parameterMap2.get("sign"));
//        } catch (Exception e) {
//            e.printStackTrace();
//            throw new CustomException("下单失败，请重试");
//        }
//        parameterMap2.remove("appId");
//        return parameterMap2;
//
//    }

    /**
     * 通过code 获取用户信息
     * @param code 小程序code
     * @return
     */
    public Auth2SessionBo authCode2Session(String code){
        String url = weiXinInfo.getCodeUrl()
                .replace("APPID", weiXinInfo.getAppId())
                .replace("SECRET", weiXinInfo.getAppSecret())
                .replace("JSCODE", code);

        final Auth2SessionBo forObject = restTemplate.getForObject(url, Auth2SessionBo.class);
        if(forObject == null){
            throw new CustomException("获取信息失败");
        }
        if(StringUtils.isNotBlank(forObject.getOpenid())){
            return forObject;
        }else{
            throw new CustomException(forObject.getErrmsg());
        }


    }

    /**
     *  根据商户内部订单号，查询订单支付状态
     * @param outTradeNo 商户系统内部订单号，只能是数字、大小写字母_-*且在同一个商户号下唯一
     * @return CheckPayResult 封装订单支付结果，或者失败异常
     */
//    public CheckPayResult checkOrder(String outTradeNo) throws Exception {
//        if(StringUtils.isBlank(outTradeNo)){
//            throw new CustomException("参数缺失");
//        }
//
//        URIBuilder uriBuilder = new URIBuilder(weiXinInfo.getCheckPayUrl()+outTradeNo+"?mchid="+weiXinInfo.getMchId());
//        HttpGet httpGet = new HttpGet(uriBuilder.build());
//        httpGet.addHeader("Accept", "application/json");
//        CloseableHttpResponse response = httpClient.execute(httpGet);
//        System.out.println("response="+response.toString());
//        int statusCode = response.getStatusLine().getStatusCode();
//        if (statusCode == 200) {
//            final String s = EntityUtils.toString(response.getEntity());
//            ObjectMapper objectMapper = new ObjectMapper();
//            final CheckPayResult checkPayResult = objectMapper.readValue(s, CheckPayResult.class);
//            return checkPayResult;
//        }  else {
//            throw new IOException("request failed");
//        }
//
//    }


    /**
     *  统一下单
     * @param total 总金额 分
     * @param description 商品描述
     * @param openid 支付者openid
     * @param outTradeNo 商户系统内部订单号，只能是数字、大小写字母_-*且在同一个商户号下唯一
     * @throws IOException
     * @return prepay_id 预付订单id
     */
//    public String createOrder(Integer total,String description,String openid,String outTradeNo) throws IOException {
//        if(total ==null || StringUtils.isBlank(description) || StringUtils.isBlank(openid) || StringUtils.isBlank(outTradeNo)){
//            throw new CustomException("参数缺失");
//        }
//        //请求URL
//        HttpPost httpPost = new HttpPost(weiXinInfo.getCreateOrderUrl());
//        // 请求body参数
//        String reqdata = "{"
//                + "\"amount\": {"
//                + "\"total\": "+total+","
//                + "\"currency\": \"CNY\""
//                + "},"
//                + "\"mchid\": \""+weiXinInfo.getMchId()+"\","
//                + "\"description\": \""+description+"\","
//                + "\"notify_url\": \""+weiXinInfo.getPayBackUrl()+"\","
//                + "\"payer\": {"
//                + "\"openid\": \""+openid+"\"" + "},"
//                + "\"out_trade_no\": \""+outTradeNo+"\","
//               // + "\"goods_tag\": \"WXG\","
//                + "\"appid\": \""+weiXinInfo.getAppId()+"\"" + "}";
//        //System.err.println(reqdata);
//        StringEntity entity = new StringEntity(reqdata);
//        entity.setContentType("application/json");
//        httpPost.setEntity(entity);
//        httpPost.setHeader("Accept", "application/json");
//
//        //完成签名并执行请求
//        CloseableHttpResponse response = httpClient.execute(httpPost);
//        try {
//            System.out.println("response="+response.toString());
//            int statusCode = response.getStatusLine().getStatusCode();
//            if (statusCode == 200) {
//                //System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
//                final String s = EntityUtils.toString(response.getEntity());
//                JSONObject jsonObject = JSONObject.parseObject(s);
//                return jsonObject.getString("prepay_id");
//            } else {
//               // System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
//                throw new IOException("request failed");
//            }
//        } finally {
//            response.close();
////            httpClient.close();
//        }
//    }




    /**
    * 解密并且获取用户手机号码
    * @param encrypdata
    * @param ivdata
    * @param sessionkey
    * @return
    * @throws Exception 
    */
   
//    public String deciphering(String encrypdata, String ivdata, String sessionkey) {
//
//        byte[] encrypData = Base64.decode(encrypdata);
//        byte[] ivData = Base64.decode(ivdata);
//        byte[] sessionKey = Base64.decode(sessionkey);
//        String str="";
//    try {
//    str = decrypt(sessionKey,ivData,encrypData);
//    } catch (Exception e) {
//    // TODO Auto-generated catch block
//    e.printStackTrace();
//    }
//        System.out.println(str);
//        return str;
//
//    }
//    public static String decrypt(byte[] key, byte[] iv, byte[] encData) throws Exception {
//        AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
//        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
//        SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
//        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
//        //解析解密后的字符串
//        return new String(cipher.doFinal(encData),"UTF-8");
//      }



}
